// 思路：用双指针 cur 和 dest 把数组切割成三块
// [0, dest] -> 非0元素
// [dest+1, cur-1] -> 0元素
// [cur, n-1] -> 待处理元素

// cur 从左往右遍历过程中：
// 1. 遇到0元素，直接cur++
// 2. 遇到非0元素，swap(dest+1, cur)，dest++，cur++

class Solution {
    public void moveZeroes(int[] nums) {
        int cur = 0;          // 当前遍历指针，从头开始扫描数组
        int dest = -1;         // 目标指针，指向已处理非零序列的末尾（初始为-1表示无元素）
        int n = nums.length;  // 数组长度

        while (cur < n) {    // 遍历整个数组
            int tmp = 0;        // 临时变量用于交换（实际未使用初始值）
            if (nums[cur] != 0) {  // 发现非零元素
                // 交换 cur 和 dest+1 位置的元素
                tmp = nums[cur];          // 临时保存当前非零值
                nums[cur] = nums[dest+1]; // 将目标位置的值（必为0）移到当前位置
                nums[dest+1] = tmp;       // 将非零值插入目标位置
                dest++;                   // 目标指针后移，扩大非零序列
            }
            cur++;  // 移动当前指针（无论是否交换）
        }
    }
}